package com.wangfugui.mybatisplus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangfugui.mybatisplus.dao.DailyPnlDao;
import com.wangfugui.mybatisplus.domain.DailyPnl;
import com.wangfugui.mybatisplus.service.DailyPnlService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class DailyPnlServiceImpl extends ServiceImpl<DailyPnlDao, DailyPnl> implements DailyPnlService {

    @Override
    public void updateHolding(String stockCode) {
        LambdaUpdateWrapper<DailyPnl> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq( DailyPnl::getStockCode, stockCode)
                .set(DailyPnl::getHolding, false);
        update(wrapper);
    }

    @Override
    public void updateHolding(List<String> stockCodes) {
        if (CollectionUtils.isEmpty(stockCodes)) {
            return;
        }
        LambdaUpdateWrapper<DailyPnl> wrapper = new LambdaUpdateWrapper<>();
        wrapper.notIn( DailyPnl::getStockCode, stockCodes)
                .set(DailyPnl::getHolding, false);
        update(wrapper);
    }

    @Override
    public DailyPnl listLastHoldingOne(String stockCode, Date date) {
        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DailyPnl::getStockCode, stockCode)
//                .eq(DailyPnl::getHolding, true)
                .lt(DailyPnl::getDate, date)
                .orderByDesc(DailyPnl::getDate)
                .last("LIMIT 1");
        return getOne(wrapper);
    }

//    @Override
//    public DailyPnl listLastHoldingOne(String stockCode) {
//        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(DailyPnl::getStockCode, stockCode)
//                .eq(DailyPnl::getHolding, true)
//                .orderByDesc(DailyPnl::getDate)
//                .last("LIMIT 1");
//        return getOne(wrapper);
//    }


    @Override
    public List<DailyPnl> list(String stockCode, Date reportDate) {
        // 构建查询条件
        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
        wrapper.le(DailyPnl::getDate, reportDate)
                .eq(DailyPnl::getStockCode, stockCode) // 按 stockCode 过滤
        ;
        return list(wrapper);
    }

//    @Override
//    public List<DailyPnl> list(String stockCode) {
//        // 构建查询条件
//        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(DailyPnl::getStockCode, stockCode) // 按 stockCode 过滤
//        ;
//        return list(wrapper);
//    }

    @Override
    public List<DailyPnl> listByYear(String stockCode, Date year) {
        if (year == null) {
            throw new IllegalArgumentException("年份不能为空");
        }

        // 将 Date 转换为 LocalDate
        LocalDate localDate = year.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        int yearValue = localDate.getYear();

        // 构建查询条件
        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DailyPnl::getStockCode, stockCode) // 按 stockCode 过滤
                .le(DailyPnl::getDate, year)
                .ge(DailyPnl::getDate, LocalDate.of(yearValue, 1, 1)) // 大于等于当年第一天
                .lt(DailyPnl::getDate, LocalDate.of(yearValue + 1, 1, 1)); // 小于下一年第一天

        return this.list(wrapper);
    }

    @Override
    public List<DailyPnl> notHolding(List<String> stockCodes, Date reportDate) {
        if (reportDate == null) {
            throw new IllegalArgumentException("月份不能为空");
        }
        // Date -> LocalDate
        LocalDate localDate = reportDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        YearMonth yearMonth = YearMonth.from(localDate);

        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
        wrapper.notIn(!CollectionUtils.isEmpty(stockCodes),DailyPnl::getStockCode, stockCodes)
                .ge(DailyPnl::getDate, yearMonth.atDay(1))
                .lt(DailyPnl::getDate, yearMonth.plusMonths(1).atDay(1))
                .le(DailyPnl::getDate, reportDate);

        return this.list(wrapper);
    }
    public static void main(String[] args) {
        String strWithComma = "1,234.56";
        // 去除逗号
        String strWithoutComma = strWithComma.replace(",", "");
        // 转换为BigDecimal
        BigDecimal bigDecimal = new BigDecimal(strWithoutComma);
        System.out.println(bigDecimal);
    }

    @Override
    public List<DailyPnl> listByMonthHolding(String stockCode, Date reportDate) {
        if (reportDate == null) {
            throw new IllegalArgumentException("月份不能为空");
        }
        // Date -> LocalDate
        LocalDate localDate = reportDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        YearMonth yearMonth = YearMonth.from(localDate);

        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DailyPnl::getStockCode, stockCode)
                .le(DailyPnl::getDate, reportDate)
                .eq(DailyPnl::getHolding, true)
                .ge(DailyPnl::getDate, yearMonth.atDay(1))
                .lt(DailyPnl::getDate, yearMonth.plusMonths(1).atDay(1));

        return this.list(wrapper);
    }

    @Override
    public List<DailyPnl> listByMonth(String stockCode, Date month) {
        if (month == null) {
            throw new IllegalArgumentException("月份不能为空");
        }
        // Date -> LocalDate
        LocalDate localDate = month.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        YearMonth yearMonth = YearMonth.from(localDate);

        LambdaQueryWrapper<DailyPnl> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DailyPnl::getStockCode, stockCode)
                .le(DailyPnl::getDate, month)
                .ge(DailyPnl::getDate, yearMonth.atDay(1))
                .lt(DailyPnl::getDate, yearMonth.plusMonths(1).atDay(1));

        return this.list(wrapper);
    }
}
